package cn.txy.article.service.impl;

import cn.txy.aop.anno.Logs;
import cn.txy.article.bo.ArticleTypeCountBo;
import cn.txy.article.domain.Article;
import cn.txy.article.domain.ArticleType;
import cn.txy.article.domain.TypeName;
import cn.txy.article.domain.YearAndMonth;
import cn.txy.article.mongo.BlogArticle;
import cn.txy.article.mapper.ArticleMapper;
import cn.txy.article.query.ArticleQuery;
import cn.txy.article.service.ArticleService;
import cn.txy.base.service.impl.BaseServiceImpl;
import cn.txy.config.RedisConstant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class ArticleServiceImpl extends BaseServiceImpl<Article> implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    @Logs
    public void add(Article article) {
        Date date = new Date();
        article.setCreateTime(date);
        article.setUpdateTime(date);
        article.setArticleCommentNum(0);
        article.setArticleReadCount(0);
        article.setArticleStarNum(0);
//        todo 登录做了之后才可以做
//        article.setPublishId();
        super.add(article);
        BlogArticle blogArticle = BlogArticle.of(article);
        mongoTemplate.insert(blogArticle);

    }

    @Override
    @Logs
    public void update(Article article) {
        super.update(article);
        Query query = new Query(Criteria.where("id").is(article.getId()));
        BlogArticle one = mongoTemplate.findOne(query, BlogArticle.class);
        BeanUtils.copyProperties(article,one);
        mongoTemplate.save(one);
    }

    @Override
    public void deleteById(Long id) {
        super.deleteById(id);
        mongoTemplate.remove(new Query(Criteria.where("id").is(id)),BlogArticle.class);
    }

    @Override
    public List<Article> queryPage(ArticleQuery query) {
        return articleMapper.queryPage(query);
    }

    @Override
    public List<Article> selectPage(ArticleQuery articleQuery) {
        return articleMapper.selectPage(articleQuery);
    }

    @Override
    public Integer star(HttpServletRequest request, Long id) {
        //获取当前人的ip地址
        String localAddr = request.getRemoteAddr();
//        System.out.println(localAddr);
        if(!redisTemplate.hasKey(RedisConstant.ARTICLE_STAR_NUM+localAddr)){
            redisTemplate.opsForValue().set(RedisConstant.ARTICLE_STAR_NUM+localAddr,1,24, TimeUnit.HOURS);
            Article article = articleMapper.findById(id);
            article.setArticleStarNum(article.getArticleStarNum()+1);
            articleMapper.update(article);
            return article.getArticleStarNum();
        }
        return null;
    }
    @Override
    public Integer read(HttpServletRequest request, Long id) {
        String localAddr = request.getRemoteAddr();
        if (!redisTemplate.hasKey(RedisConstant.ARTICLE_READ_COUNT + localAddr)) {
            redisTemplate.opsForValue().set(RedisConstant.ARTICLE_READ_COUNT + localAddr, 1, 24, TimeUnit.HOURS);
            Article article = articleMapper.findById(id);
            // 修改为更新阅读量
            article.setArticleReadCount(article.getArticleReadCount() + 1);
            articleMapper.update(article);
            return article.getArticleReadCount();
        }
        return null;
    }

    @Override
    public List<YearAndMonth> findByYearAndMonth() {
        return articleMapper.findByYearAndMonth();
    }

    @Override
    public List<Map<String, Object>> getTop6StarArticles() {
        return articleMapper.selectTop6StarArticles();
    }

    @Override
    public List<ArticleType> getTop5ArticleTypes() {
        return articleMapper.getTop5ArticleTypes();
    }

    @Override
    public List<ArticleTypeCountBo> articleTypeCount() {
        return articleMapper.articleTypeCount();
    }

    @Override
    public Map<Integer, List<Article>> archives() {
        //所有数据
        List<Article> all = articleMapper.findAll();
        Map<Integer, List<Article>> collect = all.stream()
                .filter(article -> article.getUpdateTime()!=null)//过滤哪些为null的数据
                .filter(article -> article.getArticleState()!=1)//过滤哪些为null的数据
                .collect(Collectors.groupingBy(article -> {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(article.getUpdateTime());
                    return calendar.get(Calendar.YEAR);
                }));


        return collect;
    }
}
